package com.chunuo.aclservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chunuo.aclservice.entity.Permission;
import com.chunuo.aclservice.entity.Role;
import com.chunuo.aclservice.entity.RolePermission;
import com.chunuo.aclservice.entity.User;
import com.chunuo.aclservice.helper.MemuHelper;
import com.chunuo.aclservice.mapper.PermissionMapper;
import com.chunuo.aclservice.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2020-08-05
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RolePermissionService rolePermissionService;



    /**
     * 获取管理员菜单权限
     * @return
     */
//    @Override
//    public List<Permission> queryAllMenu() {
//        // 首先必须要登录，然后获取用户信息，比如id
//        String userId = null;
//        //获取当前登录用户用户名
//        String username = SecurityContextHolder.getContext().getAuthentication().getName();
//        User user = userService.selectByUsername(username);
//        if(user!=null){
//            userId = user.getId();
//        }
//        // 获取到用户信息
////        User user = userService.getById(userId);
//        // 获取用户的角色
//        Map userBindRole = userRoleService.getUserBindRole(userId);
//        List<Role> roles = (List<Role>) userBindRole.get("assignRoles");
//        System.out.println("roles === "+roles);
//
//        //用户角色的id集合
//        List<String> collect = roles.stream().map(entity -> {
//            return entity.getId();
//        }).collect(Collectors.toList());
//        System.out.println("roleIds === "+collect);
//
//        // 根据角色获取权限
//        List<Permission> userPermission = getUserBindPermission(collect);
//        System.out.println("permission === "+userPermission);
//
//        return userPermission;
//    }
    // 获取的是所有permission
    @Override
    public List<Permission> queryAllMenu() {
        // 获取所有的权限、并且 根据id排序
        List<Permission> allPermissionList = this.list(new QueryWrapper<Permission>().
                orderByAsc("CAST(id AS SIGNED)"));

        List<Permission> build = build(allPermissionList);

        return build;
    }

    /**
     * 递归删除菜单
     * @param id
     */
    @Override
    public void removeChildById(String id) {
        //获取选中要删除的id
        Permission permission = this.getById(id);
        //存储准备删除的id
        List<String> ids = new ArrayList<>();
        ids.add(permission.getId());
        //递归查所有子节点的id
        if(permission.getChildren()!=null&&permission.getChildren().size()>0){
            getRemoveChildNode(ids,permission.getChildren());
        }
        //批量删除
        baseMapper.deleteBatchIds(ids);
    }

    /**
     * 根据用户id查询权限值
     * @param userId
     * @return
     */
    @Override
    public List<String> selectPermissionValueByUserId(String userId) {
        System.out.println("用户id "+userId);

        //根据用户id获取角色
        List<Role> roleList = roleService.selectRoleByUserId(userId);
        System.out.println("获取用户角色");
        System.out.println(roleList);

        List<String> roleIds = roleList.stream().map(entity -> {
            return entity.getId();
        }).collect(Collectors.toList());
        System.out.println("获取用户角色id");
        System.out.println(roleIds);

        //获取用户匹配的所有权限
        List<Permission> userBindPermission = findUserBIndPermission(roleIds);
        System.out.println("获取用户权限");
        System.out.println(userBindPermission);

        //只获取权限值
        List<String> collect = userBindPermission.stream().filter(entity -> {
            if (!StringUtils.isEmpty(entity.getPermissionValue())) {
                return true;
            }
            return false;
        }).map(entity -> {
            return entity.getPermissionValue();
        }).collect(Collectors.toList());

        System.out.println("获取用户权限值");
        System.out.println(collect);
        return collect;
    }

    @Override
    public List<JSONObject> selectPermissionByUserId() {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userService.selectByUsername(username);
        List<Permission> permissionList  = getUserBindPermission(user.getId());
        System.out.println("selectPermissionByUserId() => permissionList");
        System.out.println(permissionList);
        List<JSONObject> result = MemuHelper.bulid(permissionList);
        return result;
    }

    /**
     * 递归查找删除元素的子节点id
     * @param ids
     * @param permissionList
     */
    private void getRemoveChildNode(List<String> ids, List<Permission> permissionList) {
        for(Permission permission:permissionList){
            ids.add(permission.getId());
            if(permission.getChildren()!=null&&permission.getChildren().size()>0){
                getRemoveChildNode(ids,permission.getChildren());
            }
        }
    }


    /**
     * 获取所有的permission
     * @param roleIds
     * @return
     */
    @Override
    public List<Permission> findUserBIndPermission(List<String> roleIds){
        // 获取所有的权限、并且 根据id排序
        List<Permission> allPermissionList = this.list(new QueryWrapper<Permission>().
                orderByAsc("CAST(id AS SIGNED)"));
        // 获取用户所有的权限
        List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().
                in("role_id", roleIds));
        System.out.println("查看用户所有角色权限的Id  rolePermissionList  ========" + rolePermissionList);

        // 封装成权限集合
        List<Permission> collect = allPermissionList.stream().filter(entity -> {
            for (RolePermission rolePermission : rolePermissionList) {
                if (entity.getId().equals(rolePermission.getPermissionId())) {
                    return true;
                }
            }
            return false;
        }).collect(Collectors.toList());
        System.out.println("用户");
        System.out.println(collect);

        return collect;
    }

    //============================================获取角色匹配的权限封装成树形===========================================//
    /**
     * 获取用户的权限
     * @param
     * @return
     */
    @Override
    public List<Permission> getUserBindPermission(List<String> roleIds) {

        List<Permission> collect = findUserBIndPermission(roleIds);
        System.out.println("用户左侧菜单权限 == ");
        System.out.println(collect);
        // 封装成树形集合
        List<Permission> build = build(collect);
        System.out.println("用户左侧菜单Build后=》》 == ");
        System.out.println(build);
        return build;
    }

    /**
     * 根据用户id获取用户的所有权限
     * @param userId
     * @return
     */
    @Override
    public List<Permission> getUserBindPermission(String userId) {
        List<Role> roles = roleService.selectRoleByUserId(userId);
        System.out.println("getUserBindPermission() =》 roles = ");
        System.out.println(roles);
        List<String> roleIds = roles.stream().map(entity -> {
            return entity.getId();
        }).collect(Collectors.toList());
        System.out.println("getUserBindPermission() =》roleIds = ");
        System.out.println(roleIds);
        return getUserBindPermission(roleIds);
    }


    /**
     * 获取角色与权限的绑定
     * @param roleId
     * @return
     */
    @Override
    public List<Permission> getRoleBindPermission(String roleId) {
        // 获取所有的权限、并且 根据id排序
        List<Permission> allPermissionList = this.list(new QueryWrapper<Permission>().
                orderByAsc("CAST(id AS SIGNED)"));

        System.out.println("获取所有的菜单权限");
        System.out.println(allPermissionList);

        // 获取该角色绑定的权限
        List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().
                eq("role_id", roleId));


        // 将获取到绑定权限后，修改全部数据中，将已被绑定的 数据改为选中
        List<Permission> collect = allPermissionList.stream().filter(permission -> {
            for (RolePermission rolePermission : rolePermissionList) {
                if (permission.getId().equals(rolePermission.getPermissionId())) {
                    permission.setSelect(true);
                    break;
                }
            }
            return true;
        }).collect(Collectors.toList());


        List<Permission> permissionList = build(collect);

        return permissionList;
    }


    // 构建成树形节点
    private List<Permission> build(List<Permission> allPermissionList) {
        List<Permission> permissionList = new ArrayList<>();
        for(Permission permission : allPermissionList){
            //当父id等于0时，则表明该节点是首节点
            if(permission.getPid().equals("0")){
                permission.setLevel(1);
                //添加进permissionList
                permissionList.add(permission);
                // 找到permission 的子节点
                findChild(allPermissionList,permission);
                return permissionList;

            }
        }
        return null;
    }

    // 递归查找子节点
    private void findChild(List<Permission> allPermissionList, Permission permission) {
        List<Permission> children = new ArrayList<>();
        for(Permission child : allPermissionList) {
            //当父id等于permission Id时，则表明该节点是permission子节点
            if (child.getPid().equals(permission.getId())) {
                child.setLevel(permission.getLevel()+1);
                // 节点统一添加到children集合中
                children.add(child);
                // 遍历子节点
                findChild(allPermissionList,child);
            }
        }
        permission.setChildren(children);
    }

}
